import socket
import pickle
import util
from eventServer import eventServer

MTU_SIZE = 1 << 20

class NetworkNode:
    def __init__(self, ip = None, port = None):
        self.ip = ip or socket.gethostname()
        self.port = port or 1234
        
        self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        self.sock.setblocking(False)
        while True:
            try:
                self.sock.bind((self.ip,self.port))
                break
            except socket.error:
                self.port += 1
                
        print "bound to", self.ip, self.port
        
        self.receiveFunctions = util.getFunctions(self,"receive_")
        
        eventServer.subscribe("update",self.pump)
        
    def kill(self):
        print "close socket"
        self.sock.close()
        
    def send(self, cmd, msg, dest):
        #print "send", cmd, msg, dest
        self.sock.sendto(pickle.dumps((cmd,msg)),dest)
        
    def pump(self, args = None):
        while True:
            try:
                packet, sender = self.sock.recvfrom(MTU_SIZE)
            except socket.error:
                return
            
            try:
                cmd, msg = pickle.loads(packet)
            except:
                return
            
            self.receive(cmd,msg,sender)
        
    def receive(self, cmd, msg, sender):
        #print "receive", cmd, msg, sender
        if cmd in self.receiveFunctions:
            self.receiveFunctions[cmd](msg,sender)

